#include <jni.h>
#include <string>
#include "dalvik.h"
#include "art_7_0.h"

typedef Object *(*FindObject)(void *thread, jobject jobject1);
typedef  void* (*FindThread)();
FindObject  findObject;
FindThread  findThread;
extern "C" {
    JNIEXPORT void JNICALL
    Java_com_dbgs_fix1lib_DexManager_replace(JNIEnv *env, jobject instance, jint sdk,
                                             jobject wrongMethod, jobject pRightMethodMethod) {

        // TODO
//    做  跟什么有关   虚拟机    java虚拟机 Method
//找到虚拟机对应的Method 结构体

        Method * pWrongMethod = (Method *) env->FromReflectedMethod(wrongMethod);
        Method * pRightMethod = (Method *) env->FromReflectedMethod(pRightMethodMethod);
        //下一步  把pRightMethod对应的object  第一个成员变量 classobject  status
        //class object
        void * dvm_hand = dlopen("libdvm.so",RTLD_NOW);
        //sdk  <10    后面有变化
        findObject= (FindObject) dlsym(dvm_hand, sdk > 10 ? "_Z20dvmDecodeIndirectRefP6ThreadP8_jobject": "dvmDecodeIndirectRef");
        findThread = (FindThread) dlsym(dvm_hand, sdk > 10 ? "_Z13dvmThreadSelfv" : "dvmThreadSelf");

        // method   所声明的Class
        jclass  methodClz = env->FindClass("java/lang/reflect/Method");
        jmethodID  pRightMethodMethodId = env->GetMethodID(methodClz,"getDeclaringClass",
                                                    "()Ljava/lang/Class;" );

        jobject ndkObject = env->CallObjectMethod(pRightMethodMethod, pRightMethodMethodId);
        ClassObject *firstFiled = (ClassObject *) findObject(findThread(), ndkObject);
        firstFiled->status=CLASS_INITIALIZED;

        pWrongMethod->accessFlags |= ACC_PUBLIC;
        pWrongMethod->methodIndex=pRightMethod->methodIndex;
        pWrongMethod->jniArgInfo=pRightMethod->jniArgInfo;
        pWrongMethod->registersSize=pRightMethod->registersSize;
        pWrongMethod->outsSize=pRightMethod->outsSize;
//    方法参数 原型
        pWrongMethod->prototype=pRightMethod->prototype;
//
        pWrongMethod->insns=pRightMethod->insns;
        pWrongMethod->nativeFunc=pRightMethod->nativeFunc;
    }


    JNIEXPORT void JNICALL
    Java_com_dbgs_fix1lib_DexManager_replaceArt(JNIEnv *env, jobject instance,
                                             jobject wrongMethod, jobject pRightMethodMethod) {
        //    art虚拟机替换  art  ArtMethod  ---》Java方法
        art::mirror::ArtMethod *pWrongMethod = (art::mirror::ArtMethod *) env->FromReflectedMethod(wrongMethod);
        art::mirror::ArtMethod *pRightMethod = (art::mirror::ArtMethod *) env->FromReflectedMethod(wrongMethod);



//        jclass jcls = env->FindClass("com/dongnao/fixdavlik/NativeStructsModel");
//
//        size_t firMid = (size_t) env->GetStaticMethodID(jcls, "f1", "()V");
//        size_t secMid = (size_t) env->GetStaticMethodID(jcls, "f2", "()V");
//
//        int size=secMid-firMid;
//        memccpy(pWrongMethod,pRightMethod,size);

        pWrongMethod->declaring_class_=pRightMethod->declaring_class_;
    pWrongMethod->dex_code_item_offset_=pRightMethod->dex_code_item_offset_;
    pWrongMethod->method_index_=pRightMethod->method_index_;
    pWrongMethod->dex_method_index_=pRightMethod->dex_method_index_;


        ////入口
    pWrongMethod->ptr_sized_fields_.entry_point_from_jni_=pRightMethod->ptr_sized_fields_.entry_point_from_jni_;
    //    机器码模式
    pWrongMethod->ptr_sized_fields_.entry_point_from_quick_compiled_code_=pRightMethod->ptr_sized_fields_.entry_point_from_quick_compiled_code_;

//  不一样
    pWrongMethod->ptr_sized_fields_.entry_point_from_jni_=pRightMethod->ptr_sized_fields_.entry_point_from_jni_;
    pWrongMethod->ptr_sized_fields_.dex_cache_resolved_methods_=pRightMethod->ptr_sized_fields_.dex_cache_resolved_methods_;
    pWrongMethod->ptr_sized_fields_.dex_cache_resolved_types_=pRightMethod->ptr_sized_fields_.dex_cache_resolved_types_;
    pWrongMethod->hotness_count_=pRightMethod->hotness_count_;
    }

}